package snafu.controller;

import java.util.Timer;
import java.util.TimerTask;

public abstract class Processor {
	public static final int INFINITY = Integer.MIN_VALUE;
	
	private boolean running;
	private int delay;
	private Timer timer;
	private int currentRound, maxRounds;
	
	public Processor(int delay, int maxRounds) {
		this.delay = delay;
		this.maxRounds = maxRounds;
		
		currentRound = 0;
		running = false;
	}
	
	public abstract void process();
	
	public synchronized void start() {
		// run check
		if (running)
			throw new IllegalStateException("simulation already running");
		running = true;
		
		// process with delay
		if (delay != 0) {
			timer = new Timer();
			timer.schedule(new ProcessingTask(), 0, delay);
			return;
		}
		
		// process without delay
		new Thread() {
			@Override
			public void run() {
				// simulate
				for (; maxRounds == INFINITY || currentRound <= maxRounds;) {
					if (maxRounds != INFINITY)
						currentRound++;
					process();
				}
				// end simulation
				Processor.this.stop();
			}
		}.start();
	}
	
	public synchronized void step() {
		if (currentRound++ >= maxRounds && maxRounds != INFINITY)
			stop();
		else
			process();
	}

	public void stop() {
		// run check
		if (!running)
			throw new IllegalStateException("simulation not running");
		
		if (timer != null)
			timer.cancel();
		running = false;
	}
	
	private class ProcessingTask extends TimerTask {
		@Override
		public void run() {
			step();
		}
	}
	
	public void setDelay(int delay) {
		this.delay = delay;
	}
	
	public int getCurrentRound() {
		return currentRound;
	}
	
	public int getMaxRounds() {
		return maxRounds;
	}
	
	public boolean isRunning() {
		return running;
	}
}
